#include "lox/chunk.h"
#include "lox/debug.h"
#include "lox/vm.h"

#include "test_lox.h"

using namespace lox;

LoxTest::LoxTest() {
//    // Have qux return true by default
//    ON_CALL(m_bar,qux()).WillByDefault(Return(true));
//    // Have norf return false by default
//    ON_CALL(m_bar,norf()).WillByDefault(Return(false));
}

LoxTest::~LoxTest() {};

void LoxTest::SetUp() {};

void LoxTest::TearDown() {};

TEST_F(LoxTest, DISASSEMBLE) {
  Chunk<double> chunk;
  chunk.WriteChunk(OP_RETURN, 1);

  size_t const_idx = chunk.AddConstants(1.2);
  chunk.WriteChunk(OP_CONSTANTS, 2);
  chunk.WriteChunk(const_idx, 2);

  chunk.WriteChunk(OP_CONSTANTS, 4);
  chunk.WriteChunk(const_idx, 4);
  DisassembleChunk(chunk, "test-disassemble");
  assert(chunk.Size() == 5);
}

TEST_F(LoxTest, INTERPRET) {
  auto chunk_sp = std::make_shared<Chunk<double>>();
  size_t const_idx = chunk_sp->AddConstants(1.2);
  chunk_sp->WriteChunk(OP_CONSTANTS, 123);
  chunk_sp->WriteChunk(const_idx, 123);

  chunk_sp->WriteChunk(OP_NEGATE, 123);
  chunk_sp->WriteChunk(OP_RETURN, 124);
  VM vm{chunk_sp};
  vm.Run();
}

TEST_F(LoxTest, BINARY_OP) {
  auto chunk_sp = std::make_shared<Chunk<double>>();
  size_t const_idx1 = chunk_sp->AddConstants(1.2);
  chunk_sp->WriteChunk(OP_CONSTANTS, 123);
  chunk_sp->WriteChunk(const_idx1, 123);

  size_t const_idx2 = chunk_sp->AddConstants(1.2);
  chunk_sp->WriteChunk(OP_CONSTANTS, 123);
  chunk_sp->WriteChunk(const_idx2, 123);

  chunk_sp->WriteChunk(OP_MULTIPLY, 123);

  chunk_sp->WriteChunk(OP_RETURN, 124);
  VM vm{chunk_sp};
  vm.Run();
}

